﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using Utilities;

namespace BusinessLogicLayer
{
    public class TangCaManager
    {
        ActionResultAsList<TangCa> Parser(DataRow row)
        {
            ActionResultAsList<TangCa> rs = new ActionResultAsList<TangCa>();
            TangCa tc = new TangCa();

            // Mã nhân viên
            string matc = row[0].ToString().Trim();
            if (String.IsNullOrEmpty(matc))
                rs.AddException(new Exception("Không đúng định dạng mã tăng ca. "));
            else
                tc.MaTangCa = matc;

            // Kiem tra ngay bat đầu
            try
            {
                tc.NgayBD = Convert.ToDateTime(row[1]);
            }
            catch (Exception)
            {
                rs.AddException(new Exception("Không đúng định dạng ngày bắt đầu. "));
            }

            // Kiểm tra ngày kết thúc
            try
            {
                tc.NgayKT = Convert.ToDateTime(row[2]);
            }
            catch (Exception)
            {
                rs.AddException(new Exception("Không đúng định dạng ngày kết thúc. "));
            }

            try
            {
                if (tc.NgayKT <= tc.NgayBD)
                    rs.AddException(new Exception("Ngày kết thúc bé hơn ngày bắt đầu."));
            }
            catch (Exception)
            {
            }

            // Kiem tra giờ bắt đầu
            try
            {
                tc.GioBatDau = Convert.ToDateTime(row[3]);
            }
            catch (Exception)
            {
                rs.AddException(new Exception("Không đúng định dạng giờ bắt đầu. "));
            }

            // Kiểm tra giờ kết thúc
            try
            {
                tc.GioKetThuc = Convert.ToDateTime(row[4]);
            }
            catch (Exception)
            {
                rs.AddException(new Exception("Không đúng định dạng giờ kết thúc. "));
            }

            try
            {
                if (tc.GioKetThuc <= tc.GioBatDau)
                    rs.AddException(new Exception("Giờ kết thúc bé hơn giờ bắt đầu."));
            }
            catch (Exception)
            {
            }

            rs.ObjectList.Add(tc);
            return rs;
        }


        public ActionResultAsList<TangCa> ThemTangCa(DataTable Table)
        {
            ActionResultAsList<TangCa> rs = new ActionResultAsList<TangCa>();
            int dem = 0;
            foreach (DataRow r in Table.Rows)
            {
                ActionResultAsList<TangCa> re = Parser(r);
                string error = "Dòng " + dem + ":\n";
                if (!re.Success)
                {
                    error += re.ToString();
                }
                else
                {
                    ActionResult ss = ThemTangCa(re.ObjectList[0],null);
                    if (ss.Success)
                    {

                        rs.ObjectList.Add(re.ObjectList[0]);
                    }
                    else
                    {
                        error += ss.ToString();
                    }
                }
                if (error != "Dòng " + dem++ + ":\n")
                    rs.AddException(new Exception(error));
            }
            return rs;
        }


        public ActionResult ThemTangCa(TangCa entity, List<DKTangCa> dsdk)
        {
            ActionResult rs = new ActionResult();
            using (var tra = new TransactionScope())
            {
                using (QLNVDbContext ctx = new QLNVDbContext())
                {
                    try
                    {
                        TangCa tc = ctx.TangCas.Where(n => n.MaTangCa == entity.MaTangCa).FirstOrDefault<TangCa>();
                        if (tc == null)
                        {
                            ctx.TangCas.Add(entity);
                            ctx.SaveChanges();
                            if (dsdk == null)
                                tra.Complete();
                            else
                            {
                                var rsdk = new DKTangCaManager().ThemDanhSachDKTangCa(dsdk);
                                if (rsdk.Success)
                                    tra.Complete();
                                else
                                    rs.Exceptions.AddRange(rsdk.Exceptions);
                            }
                        }
                        else
                            rs.AddException(new Exception("Đã tồn tại mã tăng ca: " + entity.MaTangCa + "."));
                    }
                    catch (Exception ex)
                    {
                        Logger.Write(ex.Message);
                        rs.AddException(ex);
                    }
                }
            }
            return rs;
        }

        public ActionResult CapNhatTangCa(TangCa entity, List<DKTangCa> dsdk)
        {
            using (var tra = new TransactionScope())
            {
                ActionResult rs = new ActionResult();
                using (QLNVDbContext ctx = new QLNVDbContext())
                {
                    try
                    {
                        TangCa tc = ctx.TangCas.Where(n => n.MaTangCa == entity.MaTangCa).FirstOrDefault<TangCa>();
                        if (tc != null)
                        {
                            DKTangCaManager dkmanager = new DKTangCaManager();
                            ActionResult rsdk = dkmanager.XoaDKTangCa(tc.MaTangCa);
                            rs.Exceptions.AddRange(rsdk.Exceptions);
                            rsdk = dkmanager.ThemDanhSachDKTangCa(dsdk);
                            rs.Exceptions.AddRange(rsdk.Exceptions);
                            tc.NgayBD = entity.NgayBD;
                            tc.NgayKT = entity.NgayKT;
                            tc.GioBD = entity.GioBD;
                            tc.GioKT = entity.GioKT;
                            ctx.Entry(tc).State = System.Data.Entity.EntityState.Modified;
                            ctx.SaveChanges();
                            if (rs.Success)
                                tra.Complete();
                        }
                        else
                            rs.AddException(new Exception("Không tồn tại mã tăng ca: " + entity.MaTangCa + "."));
                    }
                    catch (Exception ex)
                    {
                        Logger.Write(ex.Message);
                        rs.AddException(ex);
                    }
                }
                return rs;
            }
        }

        public ActionResult XoaTangCa(string MaTangCa)
        {
            using (var tra = new TransactionScope())
            {
                ActionResult rs = new ActionResult();
                using (QLNVDbContext ctx = new QLNVDbContext())
                {
                    try
                    {
                        TangCa np = ctx.TangCas.Where(a => a.MaTangCa == MaTangCa).FirstOrDefault<TangCa>();
                        if (np != null)
                        {
                            rs.Exceptions.AddRange(new DKTangCaManager().XoaDKTangCa(MaTangCa).Exceptions);
                            ctx.Entry(np).State = System.Data.Entity.EntityState.Deleted;
                            ctx.SaveChanges();
                            if (rs.Success)
                                tra.Complete();
                        }
                        else
                            rs.AddException(new Exception("Không tồn tại mã tăng ca: " + MaTangCa + "."));
                    }
                    catch (Exception ex)
                    {
                        Logger.Write(ex.Message);
                        rs.AddException(ex);
                    }
                }
                return rs;
            }
        }

        public ActionResultAsList<TangCa> LayDanhSachTangCa()
        {
            ActionResultAsList<TangCa> rs = new ActionResultAsList<TangCa>();
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    rs.ObjectList = ctx.TangCas.Include("DKTangCas").ToList();
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    rs.AddException(ex);
                }
            }
            return rs;
        }

        public ActionResultAsList<TangCa> LayTangCa(string MaTangCa)
        {
            ActionResultAsList<TangCa> rs = new ActionResultAsList<TangCa>();
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    rs.ObjectList = ctx.TangCas.Include("DKTangCas").Include("DKTangCas.NhanVien").Where(s => s.MaTangCa == MaTangCa).ToList();
                    if (rs.ObjectList.Count == 0)
                        rs.AddException(new Exception("Không lấy được thông tin tăng ca có mã " + MaTangCa));
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    rs.AddException(ex);
                }
            }
            return rs;
        }

        public ActionResultAsList<TangCa> LayDanhSachTangCaHienHanh()
        {
            return TimTheoNgay(DateTime.Today);
        }

        public ActionResultAsList<NhanVien> LayDanhSachNhanVien(DateTime ngay, string MaTangCa)
        {
            ActionResultAsList<NhanVien> rs = new ActionResultAsList<NhanVien>();
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    rs.ObjectList = ctx.NhanViens.Where(nv => nv.TrangThai != TrangThaiNV.NghiViec && nv.TrangThai != TrangThaiNV.OnSite &&
                       ctx.NghiPheps.Where(np => np.NgayDiLam > ngay && np.NgayNghi <= ngay &&
                           np.MaNhanVien == nv.MaNhanVien).FirstOrDefault<NghiPhep>() == null &&
                       ctx.DKTangCas.Where(dk => dk.MaTangCa != MaTangCa && dk.NgayDangKy == ngay && dk.MaNhanVien == nv.MaNhanVien).FirstOrDefault<DKTangCa>() == null).ToList();

                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    rs.AddException(ex);
                }
            }
            return rs;
        }

        public ActionResultAsList<TangCa> TimTheoNgay(DateTime date)
        {
            ActionResultAsList<TangCa> rs = new ActionResultAsList<TangCa>();
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    rs.ObjectList = ctx.TangCas.Include("DKTangCas").Where(tc => tc.NgayKT >= date && tc.NgayBD <= date).ToList();
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    rs.AddException(ex);
                }
            }
            return rs;
        }

        public string LayMaMoi()
        {
            string mamoi = "";
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    var tc = ctx.TangCas.OrderByDescending(s => s.MaTangCa).FirstOrDefault<TangCa>();
                    int ma = 0;
                    try
                    {
                        ma = Convert.ToInt32(tc.MaTangCa.Substring(2)) + 1;
                    }
                    catch
                    {
                        ma = 1;
                    }
                    if (tc == null)
                        mamoi = "TC00001";
                    else
                    {
                        mamoi = "TC";
                        for (int i = 0; i < 5-ma.ToString().Length; i++)
                            mamoi += "0";
                        mamoi += ma.ToString();
                    }
                    while (true)
                    {
                        tc = ctx.TangCas.Where(s => s.MaTangCa == mamoi).FirstOrDefault<TangCa>();
                        if (tc == null)
                            break;
                        ++ma;
                        mamoi = "TC";
                        for (int i = 0; i < 5-ma.ToString().Length; i++)
                            mamoi += "0";
                        mamoi += ma.ToString();
                    }
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                }
            }
            return mamoi;
        }
    }
}
